<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="cache-control" content="no-cache">
<title>Genivia - The gSOAP WS-Trust Extensible Framework</title>
<link href="genivia_tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="genivia_content.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="top">
 <div id="titlearea">
  <table height="72px" width="100%" cellspacing="0" cellpadding="0">
   <tbody>
    <tr>
     <td width="10%">&nbsp;</td>
     <td width="175px"><a href="https://www.genivia.com"><img alt="Genivia" src="GeniviaLogo2_trans_noslogan.png"/></a></td>
     <td class="tab_home"><a href="https://www.genivia.com">Home</a></td>
     <td class="tab_home"><a href="https://www.genivia.com/docs.html">Documentation</a></td>
     <td>
      <div style="float: right; font-size: 18px; font-weight: bold;">The gSOAP WS-Trust Extensible Framework</div>
      <br>
      <div style="float: right; font-size: 10px;">updated Thu Apr 15 2021 by Robert van Engelen</div>
     </td>
     <td width="10%">&nbsp;</td>
    </tr>
   </tbody>
  </table>
 </div>
<!-- Generated by Doxygen 1.8.11 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li class="current"><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">The gSOAP WS-Trust Extensible Framework </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#wst_1">The gSOAP WS-Trust Extensible Framework</a></li>
<li class="level1"><a href="#wst_2">WS-Trust Bindings</a></li>
<li class="level1"><a href="#wst_3">Expanding the Current WS-Trust Bindings</a></li>
<li class="level1"><a href="#wst_4">Predefined WS-Trust Operations</a><ul><li class="level2"><a href="#wst_soap_wst_request_saml_token">wst_soap_wst_request_saml_token</a></li>
<li class="level2"><a href="#wst_soap_wst_request_psha1_token">wst_soap_wst_request_psha1_token</a></li>
<li class="level2"><a href="#wst_soap_wst_request_psha256_token">wst_soap_wst_request_psha256_token</a></li>
</ul>
</li>
<li class="level1"><a href="#wst_5">Using the wst Plugin for Servers</a></li>
</ul>
</div>
<div class="textblock"><h1><a class="anchor" id="wst_1"></a>
The gSOAP WS-Trust Extensible Framework</h1>
<p>The material in this section relates to the WS-Trust specification.</p>
<p>The WS-Trust framework is extensible. New client-side and server-side WS-Trust operations can be added. Several predefined operations are included to get you started. The list of predefined operations will be expanded over time. Please inquire Genivia tech support services.</p>
<p>To use the WS-Trust framework, make sure that the <code><a class="el" href="wst_8h.html">wst.h</a></code> specification is imported in the .h file for soapcpp2, e.g. after running wsdl2h check the generated .h file:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#import &quot;<a class="code" href="wst_8h.html">wst.h</a>&quot;</span></div></div><!-- fragment --><p>If the import is not there, add it manually. Then run soapcpp2 as usual with option <code>-Iimport</code> to import <a class="el" href="wst_8h.html">wst.h</a> from the import directory.</p>
<p>The <a class="el" href="wst_8h.html">wst.h</a> and the WS-Trust-dependent <a class="el" href="wstx_8h.html">wstx.h</a> and other gSOAP-specific .h header files are located in the import directory of the gSOAP package. These files define the WS-Trust and other WS-* protocol header elements and types. The <a class="el" href="wstx_8h.html">wstx.h</a> header file defines the WS-Trust RequestSecurityTokenRequest and RequestSecurityTokenRequestCollection operations.</p>
<p>Compile your code with <code>-DWITH_DOM</code> and <code>-DWITH_OPENSSL</code> to enable WS-Security plugin API features.</p>
<p>Compile and link your code with wsseapi.c and <a class="el" href="wstapi_8c.html">wstapi.c</a>, and include wsseapi.h and <a class="el" href="wstapi_8h.html">wstapi.h</a> in your code.</p>
<p>Internally, the <a class="el" href="wstapi_8c.html">wstapi.c</a> code enables SOAP 1.2 messaging. This will not affect your SOAP 1.1 messaging.</p>
<h1><a class="anchor" id="wst_2"></a>
WS-Trust Bindings</h1>
<p>The WS-Trust bindings in <a class="el" href="wst_8h.html">wst.h</a> in the import directory were generated from the WS-Trust schema for you with the wsdl2h tool and WS/WS-typemap.dat as follows: </p><pre class="fragment">wsdl2h -cgyex -o wst.h -t WS/WS-typemap.dat WS/WS-Trust.xsd
</pre><p>The following modifications to <a class="el" href="wst_8h.html">wst.h</a> are <b>required</b> to be made after generating <a class="el" href="wst_8h.html">wst.h</a> with wsdl2h:</p>
<ul>
<li>Remove <code>//gsoapopt</code></li>
<li>Change <code><a href="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512</a></code> to remove the trailing <code>/</code> (slash)</li>
<li>Change <code>//gsoap wst schema namespace</code> directive to <code>//gsoap wst schema import</code> directive</li>
<li>Add <code>#import "wsp_appliesto.h"</code></li>
<li>Add <code>#import "wstx.h"</code> at the end of the definitions in <a class="el" href="wst_8h.html">wst.h</a></li>
</ul>
<h1><a class="anchor" id="wst_3"></a>
Expanding the Current WS-Trust Bindings</h1>
<p>To expand or customize the WS-Trust bindings by adding (or removing) content model elements to the RequestSecurityToken and RequestSecurityTokenResponse, edit WS/WS-typemap.dat for the following two definition blocks: </p><pre class="fragment">wst__RequestSecurityTokenType = $\
    _wsp__AppliesTo_*                    wsp__AppliesTo;
wst__RequestSecurityTokenType = $\
    char*                                KeyType;
wst__RequestSecurityTokenType = $\
    char*                                RequestType;
wst__RequestSecurityTokenType = $\
    char*                                TokenType;
wst__RequestSecurityTokenType = $\
    wst__EntropyType*                    Entropy;
wst__RequestSecurityTokenType = $\
    char*                                ComputedKeyAlgorithm;
wst__RequestSecurityTokenType = $\
    unsigned int*                        KeySize;
wst__RequestSecurityTokenType = $\
    struct wst__BinaryExchangeType*      BinaryExchange;
wst__RequestSecurityTokenType = $\
    struct wst__AuthenticatorType*       Authenticator;

wst__RequestSecurityTokenResponseType = $\
    struct wst__RequestedSecurityTokenType* RequestedSecurityToken;
wst__RequestSecurityTokenResponseType = $\
    struct wst__RequestedReferenceType*  RequestedAttachedReference;
wst__RequestSecurityTokenResponseType = $\
    struct wst__RequestedReferenceType*  RequestedUnattachedReference;
wst__RequestSecurityTokenResponseType = $\
    struct wst__RequestedProofTokenType* RequestedProofToken;
wst__RequestSecurityTokenResponseType = $\
    struct wst__RequestedTokenCancelledType* RequestedTokenCancelled;
wst__RequestSecurityTokenResponseType = $\
    char*                                KeyType;
wst__RequestSecurityTokenResponseType = $\
    char*                                RequestType;
wst__RequestSecurityTokenResponseType = $\
    char*                                TokenType;
wst__RequestSecurityTokenResponseType = $\
    wst__EntropyType*                    Entropy;
wst__RequestSecurityTokenResponseType = $\
    struct wst__BinaryExchangeType*      BinaryExchange;
wst__RequestSecurityTokenResponseType = $\
    struct wst__AuthenticatorType*       Authenticator;
</pre><p>For example, to add the <code>wst:Lifetime</code> element to the RequestSecurityTokenResponse add the following two lines: </p><pre class="fragment">wst__RequestSecurityTokenResponseType = $\
    wst__LifetimeType*                   Lifetime;
</pre><p>where <code><a class="el" href="structwst_____lifetime_type.html" title="&quot;http://docs.oasis-open.org/ws-sx/ws-trust/200512/&quot;:LifetimeType is a complexType. ">wst__LifetimeType</a></code> is declared in <a class="el" href="wst_8h.html">wst.h</a>. The pointer makes it optional.</p>
<p>Then follow the instructions in the previous section to regenerate <a class="el" href="wst_8h.html">wst.h</a>.</p>
<p>Given the new <code>Lifetime</code> element, the <a class="el" href="wstapi_8c.html">wstapi.c</a> framework can be extended to use this element information as follows:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span><a class="code" href="structwst_____request_security_token_response_type.html">wst__RequestSecurityTokenResponseType</a> response;</div><div class="line">time_t expires = 0; <span class="comment">// no expiration</span></div><div class="line">...</div><div class="line">if (<a class="code" href="wstapi_8h.html#aaaac1021056bd418c229a22adfc5973f">soap_call___wst__RequestSecurityToken</a>(soap, endpoint, <a class="code" href="wstapi_8h.html#a296f9d77c6b0bdca7fa173f568d1918f">soap_wst_rst_action</a>, &amp;request, &amp;response))</div><div class="line">{</div><div class="line">  soap_set_namespaces(soap, saved_namespaces);</div><div class="line">  <span class="keywordflow">return</span> soap-&gt;error;</div><div class="line">}</div><div class="line">soap_set_namespaces(soap, saved_namespaces);</div><div class="line"><span class="keywordflow">if</span> (response.Lifetime &amp;&amp; response.Lifetime-&gt;wsu__Expires)</div><div class="line">  soap_s2dateTime(soap, response.Lifetime-&gt;wsu__Expires, &amp;expires); <span class="comment">// set expiration</span></div></div><!-- fragment --><h1><a class="anchor" id="wst_4"></a>
Predefined WS-Trust Operations</h1>
<p>This section lists the predefined WS-Trust operations implemented in <a class="el" href="wstapi_8c.html">wstapi.c</a>.</p>
<h2><a class="anchor" id="wst_soap_wst_request_saml_token"></a>
wst_soap_wst_request_saml_token</h2>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> <a class="code" href="wstapi_8h.html#a494c75d3017d3ca10fbbcba77e69caeb">soap_wst_request_saml_token</a>(<span class="keyword">struct</span> soap *soap, <span class="keyword">const</span> <span class="keywordtype">char</span> *endpoint, <span class="keywordtype">int</span> soapver, <span class="keyword">const</span> <span class="keywordtype">char</span> *applyto, <span class="keyword">const</span> <span class="keywordtype">char</span> *username, <span class="keyword">const</span> <span class="keywordtype">char</span> *password, <a class="code" href="structsaml1_____assertion_type.html">saml1__AssertionType</a> **saml1, <a class="code" href="structsaml2_____assertion_type.html">saml2__AssertionType</a> **saml2)</div></div><!-- fragment --><p>Request SAML 1.0 or SAML 2.0 token, with <code>endpoint</code> service endpoint URL (send to), <code>soapver</code> SOAP version with 1 = SOAP 1.1, 2 = SOAP 1.2 (SOAP 1.2 is recommended), <code>applyto</code> is your service domain, <code>username</code> to authenticate or NULL, <code>password</code> to authenticate or NULL, <code>saml1</code> if non-NULL, requests SAML 1.0 and upon return points to a pointer that is set to the SAML 1.0 assertion received, <code>saml2</code> if non-NULL, requests SAML 2.0 and upon return points to a pointer that is set to the SAML 2.0 assertion received.</p>
<p>Returns <code>SOAP_OK</code> on success when the assertion could be verified, with <code>saml1</code> or <code>saml2</code> set.</p>
<p>For example:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="wstapi_8h.html">wstapi.h</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;wsaapi.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;wsseapi.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;wst.nsmap&quot;</span></div><div class="line"></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span> ssl_verify(<span class="keywordtype">int</span> ok, X509_STORE_CTX *store) { <span class="keywordflow">return</span> 1; } <span class="comment">// ignore all cert warnings (bad)</span></div><div class="line"></div><div class="line">...</div><div class="line"></div><div class="line">struct soap *soap = soap_new1(SOAP_XML_INDENT);</div><div class="line"><span class="keywordtype">int</span> soapver = 2; <span class="comment">// SOAP 1.2</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *to = <span class="stringliteral">&quot;https://yourcompany.com/adfs/services/trust/13/UsernameMixed&quot;</span>;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *applyto = <span class="stringliteral">&quot;yourcompany.com&quot;</span>;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *username = <span class="stringliteral">&quot;yourusername&quot;</span>;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *password = <span class="stringliteral">&quot;yourpassword&quot;</span>;</div><div class="line"><a class="code" href="structsaml2_____assertion_type.html">saml2__AssertionType</a> *saml2;</div><div class="line"><span class="comment">// register wsa plugin (optional, only if the client requires WS-Addressing rerouted messaging)</span></div><div class="line">soap_register_plugin(soap, soap_wsa);</div><div class="line"><span class="comment">// register wsse plugin</span></div><div class="line">soap_register_plugin(soap, soap_wsse);</div><div class="line"><span class="comment">// HTTPS settings</span></div><div class="line"><span class="keywordflow">if</span> (soap_ssl_client_context(soap, SOAP_SSL_DEFAULT, NULL, NULL, <span class="stringliteral">&quot;cacerts.pem&quot;</span>, NULL, NULL))</div><div class="line">{</div><div class="line">  soap_print_fault(soap, stderr);</div><div class="line">  exit(1);</div><div class="line">}</div><div class="line"><span class="comment">// HTTPS and SAML certificate verification callback</span></div><div class="line">soap-&gt;fsslverify = ssl_verify;</div><div class="line"><span class="comment">// SAML 2.0 token request</span></div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="wstapi_8h.html#a494c75d3017d3ca10fbbcba77e69caeb">soap_wst_request_saml_token</a>(soap, to, soapver, applyto, username, password, NULL, &amp;saml2))</div><div class="line">{</div><div class="line">  soap_print_fault(soap, stderr);</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">{</div><div class="line">  <span class="comment">// display subset of the assertion information</span></div><div class="line">  <span class="keywordflow">if</span> (saml2)</div><div class="line">  {</div><div class="line">    <span class="keywordtype">int</span> i;</div><div class="line">    <span class="keywordflow">for</span> (i = 0; i &lt; saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ac0b48f0f1b079dc5a71f8f70fa0e9c40">__size_AssertionType</a>; i++)</div><div class="line">    {</div><div class="line">      <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#aaa11fd8a443a32549712d1ff385d91e0">saml2__Statement</a>)</div><div class="line">      {</div><div class="line">        <span class="comment">// omitted from displaying</span></div><div class="line">      }</div><div class="line">      <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a2d261ad94e3dfc269285ca095ab3e18c">saml2__AuthnStatement</a>)</div><div class="line">      {</div><div class="line">        <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a2d261ad94e3dfc269285ca095ab3e18c">saml2__AuthnStatement</a>-&gt;<a class="code" href="structsaml2_____authn_statement_type.html#ad79b28634e3f9ecc544bee4e58d125a2">saml2__AuthnContext</a>)</div><div class="line">        {</div><div class="line">          <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a2d261ad94e3dfc269285ca095ab3e18c">saml2__AuthnStatement</a>-&gt;<a class="code" href="structsaml2_____authn_statement_type.html#ad79b28634e3f9ecc544bee4e58d125a2">saml2__AuthnContext</a>-&gt;<a class="code" href="structsaml2_____authn_context_type.html#ae93e17e0f15c795f319bb0acd38c77e8">saml2__AuthnContextClassRef</a>)</div><div class="line">            printf(<span class="stringliteral">&quot;AuthnStatement Context: %s\n&quot;</span>, saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a2d261ad94e3dfc269285ca095ab3e18c">saml2__AuthnStatement</a>-&gt;<a class="code" href="structsaml2_____authn_statement_type.html#ad79b28634e3f9ecc544bee4e58d125a2">saml2__AuthnContext</a>-&gt;<a class="code" href="structsaml2_____authn_context_type.html#ae93e17e0f15c795f319bb0acd38c77e8">saml2__AuthnContextClassRef</a>);</div><div class="line">        }</div><div class="line">      }</div><div class="line">      <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#abcb6397093be93760fec318dde4f5fc9">saml2__AuthzDecisionStatement</a>)</div><div class="line">      {</div><div class="line">        <span class="comment">// omitted from displaying</span></div><div class="line">      }</div><div class="line">      <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a56389c5b16a309fa65ff6aea4b33e101">saml2__AttributeStatement</a>)</div><div class="line">      {</div><div class="line">        <span class="keywordtype">int</span> j;</div><div class="line">        <span class="keywordflow">for</span> (j = 0; j &lt; saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a56389c5b16a309fa65ff6aea4b33e101">saml2__AttributeStatement</a>-&gt;<a class="code" href="structsaml2_____attribute_statement_type.html#a5d801d170eeb4c93c01b69e05b3d590d">__size_AttributeStatementType</a>; j++)</div><div class="line">        {</div><div class="line">          <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a56389c5b16a309fa65ff6aea4b33e101">saml2__AttributeStatement</a>-&gt;<a class="code" href="structsaml2_____attribute_statement_type.html#a3bcb09e33fb9ea4d350f6e46011c547e">__union_AttributeStatementType</a>[j].<a class="code" href="structsaml2_____attribute_statement_type_1_1____saml2____union___attribute_statement_type.html#a87c7f56823c3b69eb1d18d28cb08d7e9">saml2__Attribute</a>)</div><div class="line">          {</div><div class="line">            <span class="keywordtype">int</span> k;</div><div class="line">            <span class="keywordflow">for</span> (k = 0; k &lt; saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a56389c5b16a309fa65ff6aea4b33e101">saml2__AttributeStatement</a>-&gt;<a class="code" href="structsaml2_____attribute_statement_type.html#a3bcb09e33fb9ea4d350f6e46011c547e">__union_AttributeStatementType</a>[j].<a class="code" href="structsaml2_____attribute_statement_type_1_1____saml2____union___attribute_statement_type.html#a87c7f56823c3b69eb1d18d28cb08d7e9">saml2__Attribute</a>-&gt;<a class="code" href="structsaml2_____attribute_type.html#afded75a00ff6e69bd3f2bf4a5f18273f">__sizeAttributeValue</a>; k++)</div><div class="line">              printf(<span class="stringliteral">&quot;Type: %s\nValue: %s\n&quot;</span>, saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a56389c5b16a309fa65ff6aea4b33e101">saml2__AttributeStatement</a>-&gt;<a class="code" href="structsaml2_____attribute_statement_type.html#a3bcb09e33fb9ea4d350f6e46011c547e">__union_AttributeStatementType</a>[j].<a class="code" href="structsaml2_____attribute_statement_type_1_1____saml2____union___attribute_statement_type.html#a87c7f56823c3b69eb1d18d28cb08d7e9">saml2__Attribute</a>-&gt;<a class="code" href="structsaml2_____attribute_type.html#afc02badb5cd15295108deb918c2f1eca">Name</a>, saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#a1daccbfa3c68029f2fcb4b727408d981">__union_AssertionType</a>[i].<a class="code" href="structsaml2_____assertion_type_1_1____saml2____union___assertion_type.html#a56389c5b16a309fa65ff6aea4b33e101">saml2__AttributeStatement</a>-&gt;<a class="code" href="structsaml2_____attribute_statement_type.html#a3bcb09e33fb9ea4d350f6e46011c547e">__union_AttributeStatementType</a>[j].<a class="code" href="structsaml2_____attribute_statement_type_1_1____saml2____union___attribute_statement_type.html#a87c7f56823c3b69eb1d18d28cb08d7e9">saml2__Attribute</a>-&gt;<a class="code" href="structsaml2_____attribute_type.html#aa2376c790311f86a1dc44bd8db034d60">saml2__AttributeValue</a>[k]);</div><div class="line">          }</div><div class="line">        }</div><div class="line">      }</div><div class="line">    }</div><div class="line">    <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>)</div><div class="line">    {</div><div class="line">      <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>-&gt;<a class="code" href="structsaml2_____conditions_type.html#a6024859466803a5be5406aaf20d2da8d">NotBefore</a>)</div><div class="line">        printf(<span class="stringliteral">&quot;Not before %s\n&quot;</span>, soap_dateTime2s(soap, *saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>-&gt;<a class="code" href="structsaml2_____conditions_type.html#a6024859466803a5be5406aaf20d2da8d">NotBefore</a>));</div><div class="line">      <span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>-&gt;<a class="code" href="structsaml2_____conditions_type.html#adda07fa750e07d28e446d742dfa2f798">NotOnOrAfter</a>)</div><div class="line">        printf(<span class="stringliteral">&quot;Not on or after %s\n&quot;</span>, soap_dateTime2s(soap, *saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>-&gt;<a class="code" href="structsaml2_____conditions_type.html#adda07fa750e07d28e446d742dfa2f798">NotOnOrAfter</a>));</div><div class="line">    }</div><div class="line"></div><div class="line">  }</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">  {</div><div class="line">    printf(<span class="stringliteral">&quot;No SAML 2.0 statements!\n&quot;</span>);</div><div class="line">  }</div><div class="line">}</div><div class="line">soap_destroy(soap);</div><div class="line">soap_end(soap);</div><div class="line">soap_free(soap);</div></div><!-- fragment --><p>This prints several of the assertion's properties, including the conditions under which the assertion is valid. The <code>NotBefore</code> and <code>NotOnOrAfter</code> conditions can be checked against the current time as follows:</p>
<div class="fragment"><div class="line">time_t now = time(NULL);</div><div class="line"><span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>-&gt;<a class="code" href="structsaml2_____conditions_type.html#a6024859466803a5be5406aaf20d2da8d">NotBefore</a> &amp;&amp; *saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>-&gt;<a class="code" href="structsaml2_____conditions_type.html#a6024859466803a5be5406aaf20d2da8d">NotBefore</a> &gt; now)</div><div class="line">  ... error <span class="comment">// not valid yet</span></div><div class="line"><span class="keywordflow">if</span> (saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>-&gt;<a class="code" href="structsaml2_____conditions_type.html#adda07fa750e07d28e446d742dfa2f798">NotOnOrAfter</a> &amp;&amp; *saml2-&gt;<a class="code" href="structsaml2_____assertion_type.html#ad85b2b9e5b2a5db84778b3959da99ee9">saml2__Conditions</a>-&gt;<a class="code" href="structsaml2_____conditions_type.html#adda07fa750e07d28e446d742dfa2f798">NotOnOrAfter</a> &lt;= now)</div><div class="line">  ... error <span class="comment">// expired</span></div></div><!-- fragment --><h2><a class="anchor" id="wst_soap_wst_request_psha1_token"></a>
wst_soap_wst_request_psha1_token</h2>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> <a class="code" href="wstapi_8h.html#ad85eb228db132f10a8fc69f75365a67d">soap_wst_request_psha1_token</a>(<span class="keyword">struct</span> soap *soap, <span class="keyword">const</span> <span class="keywordtype">char</span> *endpoint, <span class="keywordtype">int</span> soapver, <span class="keyword">const</span> <span class="keywordtype">char</span> *applyto, <span class="keyword">const</span> <span class="keywordtype">char</span> *username, <span class="keyword">const</span> <span class="keywordtype">char</span> *password, <span class="keywordtype">char</span> *psha1, <span class="keywordtype">size_t</span> psha1len)</div></div><!-- fragment --><p>Request P_SHA1 token with <code>endpoint</code> service endpoint URL (send to), <code>soapver</code> SOAP version with 1 = SOAP 1.1, 2 = SOAP 1.2 (SOAP 1.2 is recommended), <code>applyto</code> your service domain, <code>username</code> to authenticate or NULL, <code>password</code> to authenticate or NULL, <code>psha1</code> is filled with the P_SHA1 result token of <code>psa1len</code> bytes.</p>
<p>Returns <code>SOAP_OK</code> on success.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;wsaapi.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="wstapi_8h.html">wstapi.h</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;wsseapi.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;wst.nsmap&quot;</span></div><div class="line"></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span> ssl_verify(<span class="keywordtype">int</span> ok, X509_STORE_CTX *store) { <span class="keywordflow">return</span> 1; } <span class="comment">// ignore all cert warnings (bad)</span></div><div class="line"></div><div class="line">...</div><div class="line"></div><div class="line">struct soap *soap = soap_new1(SOAP_XML_INDENT);</div><div class="line"><span class="keywordtype">int</span> soapver = 2; <span class="comment">// SOAP 1.2</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *to = <span class="stringliteral">&quot;https://yourcompany.com/adfs/services/trust/13/UsernameMixed&quot;</span>;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *applyto = <span class="stringliteral">&quot;yourcompany.com&quot;</span>;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *username = <span class="stringliteral">&quot;yourusername&quot;</span>;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *password = <span class="stringliteral">&quot;yourpassword&quot;</span>;</div><div class="line"><span class="keywordtype">char</span> psha1[256];</div><div class="line"><span class="comment">// register wsa plugin (optional, only if the client requires WS-Addressing rerouted messaging)</span></div><div class="line">soap_register_plugin(soap, soap_wsa);</div><div class="line"><span class="comment">// register wsse plugin</span></div><div class="line">soap_register_plugin(soap, soap_wsse);</div><div class="line"><span class="comment">// HTTPS settings</span></div><div class="line"><span class="keywordflow">if</span> (soap_ssl_client_context(soap, SOAP_SSL_DEFAULT, NULL, NULL, <span class="stringliteral">&quot;cacerts.pem&quot;</span>, NULL, NULL))</div><div class="line">{</div><div class="line">  soap_print_fault(soap, stderr);</div><div class="line">  exit(1);</div><div class="line">}</div><div class="line"><span class="comment">// HTTPS certificate verification callback</span></div><div class="line">soap-&gt;fsslverify = ssl_verify;</div><div class="line"><span class="comment">// PSHA1 token request</span></div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="wstapi_8h.html#ad85eb228db132f10a8fc69f75365a67d">soap_wst_request_psha1_token</a>(soap, to, soapver, applyto, username, password, psha1, 256))</div><div class="line">{</div><div class="line">  soap_print_fault(soap, stderr);</div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">{</div><div class="line">  <span class="comment">// use psha1[0..255]</span></div><div class="line">}</div><div class="line">soap_destroy(soap);</div><div class="line">soap_end(soap);</div><div class="line">soap_free(soap);</div></div><!-- fragment --><h2><a class="anchor" id="wst_soap_wst_request_psha256_token"></a>
wst_soap_wst_request_psha256_token</h2>
<p>Similar to the previous section, request a P_SHA256 token with:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> soap_wst_request_psha256_token(<span class="keyword">struct</span> soap *soap, <span class="keyword">const</span> <span class="keywordtype">char</span> *endpoint, <span class="keywordtype">int</span> soapver, <span class="keyword">const</span> <span class="keywordtype">char</span> *applyto, <span class="keyword">const</span> <span class="keywordtype">char</span> *username, <span class="keyword">const</span> <span class="keywordtype">char</span> *password, <span class="keywordtype">char</span> *psha256, <span class="keywordtype">size_t</span> psha256len)</div></div><!-- fragment --><h1><a class="anchor" id="wst_5"></a>
Using the wst Plugin for Servers</h1>
<p>To implement a WS-Trust server in C, run soapcpp2 as follows: </p><pre class="fragment">soapcpp2 -c -L file.h
</pre><p>where file.h has an <code>#import "wst.h"</code>. This generates the soapServer.c and soapC.c code you need to compile with <a class="el" href="wstapi_8c.html">wstapi.c</a>, wsaapi.c, wsseapi.c, smdevp.c, and mecevp.c. Link with libgsoapssl.a (or stdsoap2.c and dom.c). Use <code>-DWITH_OPENSSL</code> and <code>-DWITH_DOM</code> to compile the source code.</p>
<p>For C++, use: </p><pre class="fragment">soapcpp2 -L file.h
</pre><p>This generates the soapServer.cpp and soapC.cpp code you need to compile with <a class="el" href="wstapi_8c.html">wstapi.c</a>, wsaapi.c, wsseapi.c, smdevp.c, and mecevp.c. Link with libgsoapssl++.a (or stdsoap2.cpp and dom.cpp). Use <code>-DWITH_OPENSSL</code> and <code>-DWITH_DOM</code> to compile the source code.</p>
<p>If you prefer to use soapcpp2 option <code>-j</code> (or <code>-i</code>) to generate C++ server objects, please run soacpp2 again as follows: </p><pre class="fragment">soapcpp2 -j -L file.h
soapcpp2 -CL -pwst import/wst.h
</pre><p>This generates wstClient.cpp, which should be compiled together with the rest of your project code.</p>
<p>You should define the following service operations:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> wstService::RequestSecurityToken(<a class="code" href="structwst_____request_security_token_type.html">wst__RequestSecurityTokenType</a> *request, <a class="code" href="structwst_____request_security_token_response_type.html">wst__RequestSecurityTokenResponseType</a> *response)</div><div class="line">{</div><div class="line">  ...</div><div class="line">}</div><div class="line"><span class="keywordtype">int</span> wstService::RequestSecurityTokenCollection(<span class="keyword">struct</span> <a class="code" href="structwst_____request_security_token_collection_type.html">wst__RequestSecurityTokenCollectionType</a> *request, <span class="keyword">struct</span> <a class="code" href="structwst_____request_security_token_response_collection_type.html">wst__RequestSecurityTokenResponseCollectionType</a> *response)</div><div class="line">{</div><div class="line">  ...</div><div class="line">}</div></div><!-- fragment --><p>If you are combinding WS-Trust with other service operations, then you must also chain the service operations at the server side as follows:</p>
<div class="fragment"><div class="line"><span class="keywordflow">if</span> (soap_begin_serve(service.soap) == SOAP_OK)</div><div class="line">  <span class="keywordflow">if</span> (service.dispatch() == SOAP_NO_METHOD)</div><div class="line">    soap_serve_request(service.soap);</div></div><!-- fragment --><p>where the <code>service</code> object is an instance of the application services generated by soapcpp2 <code>-j</code>. </p>
</div></div><!-- contents -->
<hr class="footer">
<address class="footer">
Copyright (C) 2021, Robert van Engelen, Genivia Inc., All Rights Reserved.
</address>
<address class="footer"><small>
Converted on Thu Apr 15 2021 09:52:54 by <a target="_blank" href="http://www.doxygen.org/index.html">Doxygen</a> 1.8.11</small></address>
<br>
<div style="height: 246px; background: #DBDBDB;">
</body>
</html>
